package com.crimsec.utils.snmp.traptodb;

import com.crimsec.utils.snmp.IDefaults;
import com.crimsec.utils.snmp.Utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import static java.lang.System.in;
import java.util.ArrayList;
import java.util.Arrays;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.apache.log4j.Logger;

/**
 *
 */
public class App {

    private static Logger log = Logger.getLogger("traptodb.App");
    private static Utils utils;
    private StringBuilder logFileSuffix = new StringBuilder(".traptodb.log");
    private ArrayList<String> inputLines = new ArrayList<String>(17);
    private ArrayList<Exception> exlist = new ArrayList<Exception>(3);

    public static void main(String[] args) {

        App app = new App();

        try {
            app.createUtils();
        } catch (IOException e) {
            app.errExit("can not load the settings file" + e.getMessage());
        }

        try {
            app.readInput();
        } catch (IOException e) {
            app.errExit("An error occurred while reading input stream:" + e.getMessage());

        }

        try {
            app.writeToDB(args);
        } catch (Exception e) {
            String m = "An error occurred while writing to the database:";
            log.error(m + e.getMessage());
            app.exlist.add(new Exception(m + e.getMessage()));
        }

        try {
            app.writeLog(args);
        } catch (IOException e) {
            log.error("An error occurred while writing to a log file:" + e.getMessage());
        }

    }

    private void errExit(String logErr) {
        log.error(logErr);
        System.exit(-1);
    }

    private void createUtils() throws IOException {
        String cfg = System.getProperty(IDefaults.SYSCFGNAME);

        if ((cfg != null) && (!cfg.isEmpty())) {
            utils = new Utils(cfg);
        } else {
            utils = new Utils();

        }
    }

    private void readInput() throws IOException {

        BufferedReader r = new BufferedReader(new InputStreamReader(in));

        while (true) {
            String line = r.readLine();
            if ((line != null) && (!line.isEmpty())) {
                inputLines.add(line);
            } else {
                break;
            }
        }


        r.close();

    }

    private void writeToDB(String[] args) throws Exception {
        //construct copy of list because parser remove intems
        ArrayList<String> buf = new ArrayList<String>(inputLines);
        EntityManagerFactory emf = Persistence.
                createEntityManagerFactory("trap-to-postgre", utils.getJPAHibernateProps());
        EntityManager em = emf.createEntityManager();
        TraphandleParser.setEntityManager(em);
        TraphandleParser.save(
                TraphandleParser.parse(buf));
        
        em.close();
        emf.close();
    }

    private void writeLog( String[] args) throws IOException {

        ArrayList<String> buf = new ArrayList<String>(inputLines.size() + 17);
        //добавим строки входного потока
        buf.add(Utils.constLogDelimLine(Utils.MSG_LOG_STREAM));
        buf.addAll(inputLines);


        //добавим все аргументы вызова
        buf.add(Utils.constLogDelimLine(Utils.MSG_LOG_ARGS));
        buf.addAll(Arrays.asList(args));
        String date = Utils.constructSafeDateString();
        buf.add("time of call: " + date + ";format:" + Utils.DATEFORMAT); //добавим дату вызова

        if (!exlist.isEmpty()) {//добавим ошибки если есть
            logFileSuffix.append(".ERROR");
            buf.add(Utils.constLogDelimLine(Utils.MSG_LOG_ERR));
            for (Exception e : exlist) {
                buf.add(e.getMessage());
            }
        }

        FileOutputStream f = new FileOutputStream(
                File.createTempFile(
                date + ".", logFileSuffix.toString(), new File(utils.getLogBase())));
        for (String line : buf) {
            line += "\n";
            f.write(line.getBytes());
        }
        f.close();
    }
}
